package seu.xml.validator;

import java.util.ArrayList;

//元模型要素
public class ArchitectureMetaModel {
	public static final ModelSpare[] packageDiagram = { ModelSpare._package,
			ModelSpare._relation };
	public static final ModelSpare[] classDiagram = { ModelSpare._class,
			ModelSpare._relation, /* ModelSpare._note */};
	// activityDiagram is same as stateMachine
	public static final ModelSpare[] activityDiagram = { ModelSpare._state,
			ModelSpare._initialState, ModelSpare._finalState,
			ModelSpare._relation };
	public static final ModelSpare[] componentDiagram = {
			ModelSpare._component, ModelSpare._relation };
	public static final ModelSpare[] sequenceDiagram = {
			ModelSpare._SeqObjectActive, ModelSpare._relation,
			ModelSpare._class };
	public static final ModelSpare[] syssequenceDiagram = { ModelSpare._actor,
			ModelSpare._relation, ModelSpare._class };
	public static final ModelSpare[] usecaseDiagram = { ModelSpare._actor,
			ModelSpare._relation, ModelSpare._usecase };
	public static final ModelSpare[] otherDiagram = {};// unsupported diagram

	public enum UMLetDiagram {
		pkg, cls, act, state, cpnt, sqc, syssqc, uc, // supported
		dplmt, constraint;// unsupported

		/**
		 * get required contents of diagram
		 * 
		 * @return
		 */
		public ModelSpare[] parse() {
			if (this.equals(UMLetDiagram.pkg))
				return packageDiagram;
			else if (this.equals(UMLetDiagram.cls))
				return classDiagram;
			else if (this.equals(UMLetDiagram.act)
					| this.equals(UMLetDiagram.state))
				return activityDiagram;
			else if (this.equals(UMLetDiagram.cpnt))
				return componentDiagram;
			else if (this.equals(UMLetDiagram.sqc))
				return sequenceDiagram;
			else if (this.equals(UMLetDiagram.syssqc))
				return syssequenceDiagram;
			else if (this.equals(UMLetDiagram.uc))
				return usecaseDiagram;
			else
				return otherDiagram;
		}

		public String getName() {
			if (ValidationFrame.getLang() == 0) {
				if (this.equals(pkg))
					return "包图";
				else if (this.equals(cls))
					return "类图";
				else if (this.equals(act))
					return "活动图";
				else if (this.equals(state))
					return "状态图";
				else if (this.equals(cpnt))
					return "组件图";
				else if (this.equals(sqc))
					return "顺序图";
				else if (this.equals(syssqc))
					return "系统顺序图";
				else if (this.equals(uc))
					return "用例图";
				else if (this.equals(dplmt))
					return "部署图";
				else if (this.equals(constraint))
					return "约束文件";
			}
			if (ValidationFrame.getLang() == 1) {
				if (this.equals(pkg))
					return "Package Diagram";
				else if (this.equals(cls))
					return "Class Diagram";
				else if (this.equals(act))
					return "Activity Diagram";
				else if (this.equals(state))
					return "State Diagram";
				else if (this.equals(cpnt))
					return "Component Diagram";
				else if (this.equals(sqc))
					return "Sequence Diagram";
				else if (this.equals(syssqc))
					return "System Sequence Diagram";
				else if (this.equals(uc))
					return "Use Case Diagram";
				else if (this.equals(dplmt))
					return "Deployment Diagram";
				else if (this.equals(constraint))
					return "Constraint File";
			}
			throw new RuntimeException("Unknown situation!");
		}

		public static UMLetDiagram getItem(String name) {
			if (name == null)
				return null;
			if (name.equals(pkg.getName()))
				return pkg;
			else if (name.equals(cls.getName()))
				return cls;
			else if (name.equals(act.getName()))
				return act;
			else if (name.equals(state.getName()))
				return state;
			else if (name.equals(cpnt.getName()))
				return cpnt;
			else if (name.equals(sqc.getName()))
				return sqc;
			else if (name.equals(syssqc.getName()))
				return syssqc;
			else if (name.equals(uc.getName()))
				return uc;
			else if (name.equals(dplmt.getName()))
				return dplmt;
			else if (name.equals(constraint.getName()))
				return constraint;
			else
				throw new RuntimeException("Wrong Language Form!");
		}

		/**
		 * get matched diagram
		 * 
		 * @param conts
		 * @return
		 */
		public static ArrayList<UMLetDiagram> match(ModelSpare[] conts) {
			ArrayList<UMLetDiagram> match_list = new ArrayList<UMLetDiagram>();
			for (UMLetDiagram d : UMLetDiagram.values())
				if (d.check(conts).size() == 0)
					match_list.add(d);
			if (match_list.contains(sqc) || match_list.contains(syssqc))
				match_list.remove(cls);
			return match_list;
		}

		public static ArrayList<UMLetDiagram> match(ArrayList<ModelSpare> conts) {
			ModelSpare[] conts2 = new ModelSpare[conts.size()];
			for (int i = 0; i < conts2.length; i++)
				conts2[i] = conts.get(i);
			return match(conts2);
		}

		private static boolean contains(ModelSpare[] conts, ModelSpare ms) {
			if (ms == null)
				throw new RuntimeException("Bad input");
			for (ModelSpare m : conts) {
				if (m == null)
					continue;
				if (ms.equals(m))
					return true;
			}
			return false;
		}

		/**
		 * get what is missing
		 * 
		 * @param conts
		 * @return
		 */
		public ArrayList<ModelSpare> check(ModelSpare[] conts) {
			ArrayList<ModelSpare> ret = new ArrayList<ModelSpare>();
			for (ModelSpare ms : parse())
				if (!contains(conts, ms))
					ret.add(ms);
			return ret;
		}

		public ArrayList<ModelSpare> check(ArrayList<ModelSpare> conts) {
			ModelSpare[] conts2 = new ModelSpare[conts.size()];
			for (int i = 0; i < conts2.length; i++)
				conts2[i] = conts.get(i);
			return check(conts2);
		}
	}
}
